package com.example.demo03.service;

import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.example.demo03.dao.TodoItemMapper;
import com.example.demo03.entity.po.TodoItem;
import com.example.demo03.entity.response.TodoItemAPI;

/**
 * The TodoItemService class provides business logic and acts as an intermediary between the
 * controller and the data access layer (TodoItemMapper) for TodoItem operations.
 * It handles operations such as retrieving, creating, updating, and deleting TodoItems,
 * and converts between the database entity (TodoItem) and the API entity (TodoItemAPI).
 *
 * @author [Your Name]
 * @version 1.0
 * @since [Date]
 */
@Service
public class TodoItemService {

    /**
     * The TodoItemMapper used for performing database operations on TodoItem entities.
     * It is injected via Spring's dependency injection mechanism.
     */
    @Autowired
    private TodoItemMapper todoItemMapper;

    /**
     * Retrieves all TodoItems from the database and converts them to TodoItemAPI objects.
     *
     * @return a list of TodoItemAPI objects representing all TodoItems in the database
     */
    public List<TodoItemAPI> getAll() {
        List<TodoItem> todoItemsDB = todoItemMapper.findAll();
        return todoItemsDB.stream()
               .map(this::convertToAPI)
               .collect(Collectors.toList());
    }

    /**
     * Retrieves a single TodoItem by its unique identifier from the database and converts it to a TodoItemAPI object.
     *
     * @param id the unique identifier of the TodoItem
     * @return the TodoItemAPI object representing the TodoItem, or null if not found
     */
    public TodoItemAPI getById(Long id) {
        TodoItem todoItemDB = todoItemMapper.findById(id);
        return todoItemDB!= null? convertToAPI(todoItemDB) : null;
    }

    /**
     * Creates a new TodoItem in the database.
     * Converts the TodoItemAPI object to a TodoItem object before insertion.
     *
     * @param todoItemAPI the TodoItemAPI object to be created
     * @return the number of affected rows (typically 1 if the insertion is successful)
     */
    public int create(TodoItemAPI todoItemAPI) {
        TodoItem todoItemDB = convertToDB(todoItemAPI);
        return todoItemMapper.insert(todoItemDB);
    }

    /**
     * Updates an existing TodoItem in the database.
     * Converts the TodoItemAPI object to a TodoItem object before updating.
     *
     * @param todoItemAPI the TodoItemAPI object with updated information
     * @return the number of affected rows (typically 1 if the update is successful)
     */
    public int update(TodoItemAPI todoItemAPI) {
        TodoItem todoItemDB = convertToDB(todoItemAPI);
        return todoItemMapper.update(todoItemDB);
    }

    /**
     * Deletes a TodoItem from the database by its unique identifier.
     *
     * @param id the unique identifier of the TodoItem to be deleted
     * @return the number of affected rows (typically 1 if the deletion is successful)
     */
    public int deleteById(Long id) {
        return todoItemMapper.deleteById(id);
    }
    
    /**
     * Retrieves the top 10 TodoItems ordered by their score from the database and converts them to TodoItemAPI objects.
     *
     * StarRocks database is used in our system. The sorting problem is handled by the underlying DB engine,
     * so there is no need for secondary processing in the program.
     *
     * @return a list of the top 10 TodoItemAPI objects sorted by score
     */
    public List<TodoItemAPI> getTop10ByScore() {
        List<TodoItem> todoItemsDB = todoItemMapper.findTop10ByScore();
        return todoItemsDB.stream()
              .map(this::convertToAPI)
              .collect(Collectors.toList());
    }

    /**
     * Converts a TodoItem object (from the database) to a TodoItemAPI object (for API response).
     *
     * @param todoItemDB the TodoItem object from the database
     * @return the corresponding TodoItemAPI object for API response
     */
    private TodoItemAPI convertToAPI(TodoItem todoItemDB) {
        TodoItemAPI todoItemAPI = new TodoItemAPI();
        todoItemAPI.setId(todoItemDB.getId());
        todoItemAPI.setName(todoItemDB.getName());
        todoItemAPI.setDescription(todoItemDB.getDescription());
        todoItemAPI.setScore(todoItemDB.getScore());
        return todoItemAPI;
    }

    /**
     * Converts a TodoItemAPI object (from API request) to a TodoItem object (for database storage).
     * Sets default values for fields that are not exposed through the API.
     *
     * @param todoItemAPI the TodoItemAPI object from the API request
     * @return the corresponding TodoItem object for database storage
     */
    private TodoItem convertToDB(TodoItemAPI todoItemAPI) {
        TodoItem todoItemDB = new TodoItem();
        todoItemDB.setId(todoItemAPI.getId());
        todoItemDB.setName(todoItemAPI.getName());
        todoItemDB.setDescription(todoItemAPI.getDescription());
        todoItemDB.setScore(todoItemAPI.getScore());
        // Set default values or perform other processing based on business logic
        todoItemDB.setStatus("");
        todoItemDB.setCreatedAt(null);
        todoItemDB.setUpdatedAt(null);
        todoItemDB.setUserId(0L);
        return todoItemDB;
    }
}